Feat:(issue_2392) Single-value arguments can be marked as required - #2393
Feat:(issue_2392) Single-value arguments can be marked as required#2393idelchi wants to merge 3 commits into
Conversation
7c2cf0a to
526922f
Compare
|
Thanks for the PR @idelchi! Nice, well-scoped feature. The semantics correctly mirror flags (a default A few suggestions, in rough priority order:
I'd be happy to merge once #1 is decided on (align with the flags error path, or explicitly accept the divergence). |
526922f to
18fa3fa
Compare
18fa3fa to
11b3f89
Compare
dearchap
left a comment
There was a problem hiding this comment.
Issues to address
1. Duplicate enforcement with divergent error handling (moderate)
Required is checked in two places:
checkRequiredArguments(command.go:457) — pre-parse path that printsIncorrect Usage: ...+ help and setsisInError.ArgumentBase.Parse(args.go) — the arg-parsing loop only callsOnUsageError+handleExitCoder, with no help output and noisInError.
The Parse-level check is effectively dead code for the documented (required-first) ordering and only fires when a multi-value/variadic arg precedes a required arg. When it does fire, the error handling differs from the primary path (no help, different exit handling). Consider dropping one, or unifying the handling so both paths behave identically.
2. Index-based counting breaks with multi-value args (command.go:465)
index >= providedArguments assumes each declared argument consumes exactly one positional. I reproduced with:
Arguments: []Argument{
&StringArgs{Name: "rest", Min: 0, Max: -1},
&StringArg{Name: "required", Required: true},
}
cmd.Run(ctx, []string{"foo", "a", "b", "c"}) // → error: Required argument "required" not set3 args are provided but the variadic consumes them all, so the arg genuinely receives no value — but the error is misleading. The docs do tell users to declare required args before optional/multi-value args, and the Parse backstop catches it, so acceptable — but worth a comment or an error message that hints at the ordering rule.
3. Missing builtInHelp || isCompletionCommand guard (command.go:457)
checkAllRequiredFlags (command.go:424) skips both; checkRequiredArguments doesn't. Currently harmless because --help short-circuits earlier via checkHelp() (command_run.go:215) and the built-in completion subcommands have no Arguments, but it's fragile if help/completion flow changes. Add the same guard for parity.
Minor / nits
requiredArgumentinterface uses unexported methods (name(),required()), diverging from flags' publicRequiredFlagpattern (flag.go:116). Custom third-partyArgumentimplementations can never participate — fine, but inconsistent.Usage()now renders optional single args as[name]— a visible change to existing help output. It's consistent withArgumentsBaseand covered by the updatedTestArgUsage, so I'd keep it, but it deserves the explicit release-note mention (which it has).- Empty string (
"") counts as "provided" — consistent with--flag "", fine.
Net: reasonable to merge after addressing #1 and considering #2/#3.
What type of PR is this?
What this PR does / why we need it:
args.go: adds aRequiredfield toArgumentBase, same as flags have. A missing required argument returnsrequired argument "name" not set.Usage()now renders optional single args as[name], matching what{Type}Argsalready does.args_test.go: addsTestSingleRequiredArgandTestChainedRequiredArgs. TheTestArgUsageexpectation for an optional arg changes fromiato[ia].docs/v3/examples/arguments/advanced.md: short section on required arguments.godoc-current.txt/testdata/godoc-v3.x.txt: regenerated.A default
Valuedoes not satisfyRequired, same as with flags.Which issue(s) this PR fixes:
Fixes #2392
Special notes for your reviewer:
The help output change (optional single args rendering as
[name]) is a separate commit and can be dropped if unwanted.Testing
go test ./...make gfmrunfor the docs examplemake generate+make v3approvefor the godoc diff checkRelease Notes